from urllib.parse import urlencode, parse_qs
from urllib.request import urlopen
import logging
from rest_framework import status
from rest_framework.generics import GenericAPIView
from rest_framework.response import Response
from rest_framework.views import APIView
from rest_framework_jwt.settings import api_settings

from carts.utils import merge_cart_cookie_to_redis
from mall.settings import QQ_APP_ID, QQ_APP_KEY, QQ_REDIRECT_URL

# Create your views here.
from oauth.models import OAuthQQUser
from oauth.serializers import QQRegisterSerializer
from oauth.utils import QQAssistance

logger = logging.getLogger('meiduo')

class QQURLAuthView(APIView):
    """
    GET /oauth/qq/statues/
    实现出现QQ授权登录视图
    """
    def get(self, request):
        # 生成auth_url
        #
        # 请求参数请包含如下内容：
        # response_type   必须      授权类型，此值固定为“code”。
        # client_id       必须      申请QQ登录成功后，分配给应用的appid。
        # redirect_uri    必须      成功授权后的回调地址，必须是注册appid时填写的主域名下的地址，建议设置为网站首页或网站的用户中心。注意需要将url进行URLEncode。
        # state           必须      client端的状态值。用于第三方应用防止CSRF攻击，成功授权后回调时会原样带回。请务必严格按照流程检查用户与state参数状态的绑定。
        # scope           可选      scope=get_user_info
        state = request.query_params.get('state')
        qq = QQAssistance()
        auth_url = qq.get_auth_url(state)
        return Response({'auth_url':auth_url})


class GetQQTokenView(GenericAPIView):
    """
    GET /oauth/qq/users/?code=xxx
    1.前端返回从qq服务器拿到的授权code
    2.后端获取授权， 转发到qq获取以taken
    """

    serializer_class = QQRegisterSerializer

    def get(self, request):
        """
        # PC网站：https://graph.qq.com/oauth2.0/token
        # GET
        # grant_type      必须      授权类型，在本步骤中，此值为“authorization_code”。
        # client_id       必须      申请QQ登录成功后，分配给网站的appid。
        # client_secret   必须      申请QQ登录成功后，分配给网站的appkey。
        # code            必须      上一步返回的authorization
        # redirect_uri    必须      与上面一步中传入的redirect_uri保持一致。
        """

        # 获取code
        code = request.query_params.get('code')

        if code is None:
            return Response({'message': '缺少参数'}, status=status.HTTP_400_BAD_REQUEST)

        qq = QQAssistance()
        try:
            access_token = qq.get_token_by_code(code)
            openid = qq.get_openid_by_token(access_token)
        except Exception as e:
            logger.error(e)
            return Response({'message': '服务异常'}, status=status.HTTP_503_SERVICE_UNAVAILABLE)

        # 判断用户是否登陆过， 如果登陆过则存在openid
        try:
            qq_user = OAuthQQUser.objects.get(openid=openid)
        except OAuthQQUser.DoesNotExist:
            # 不存在就是第一次登陆， 前段要跳转到绑定界面
            token = OAuthQQUser.generate_save_user_token(openid)
            return Response({'access_token':token})
        else:
            # 之前登陆过就生成token返回
            user = qq_user.user

            jwt_payload_handler = api_settings.JWT_PAYLOAD_HANDLER
            jwt_encode_handler = api_settings.JWT_ENCODE_HANDLER

            payload = jwt_payload_handler(user)
            token = jwt_encode_handler(payload)
            user.token = token
            response = Response({
                'token': token,
                'user_id': user.id,
                'username': user.username
            })
            # 合并购物车数据
            response = merge_cart_cookie_to_redis(request,user,response)
            return response


    def post(self, request):
        # 第一次登陆的用户绑定账号后的提交
        serializer = self.get_serializer(data=request.data)
        serializer.is_valid(raise_exception=True)
        user = serializer.save()

        # 生成已登录的token
        jwt_payload_handler = api_settings.JWT_PAYLOAD_HANDLER
        jwt_encode_handler = api_settings.JWT_ENCODE_HANDLER

        payload = jwt_payload_handler(user)
        token = jwt_encode_handler(payload)

        response = Response({
            'token': token,
            'user_id': user.id,
            'username': user.username
        })
        response = merge_cart_cookie_to_redis(request,user,response)
        return response

